package com.mxpio.erp.asset.controller;

import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.mxpio.erp.common.vo.OrderExcuteVo;
import com.mxpioframework.common.exception.MBootException;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.client.utils.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.mxpio.erp.common.asset.entity.BorrowApply;
import com.mxpio.erp.common.asset.entity.BorrowApplyLine;
import com.mxpio.erp.common.asset.entity.BorrowOutMaterial;
import com.mxpio.erp.common.asset.service.BorrowApplyLineService;
import com.mxpio.erp.common.asset.service.BorrowApplyService;
import com.mxpio.erp.common.asset.service.BorrowOutMaterialFlowService;
import com.mxpio.erp.common.asset.service.BorrowOutMaterialService;
import com.mxpio.erp.common.enums.OrderStatusEnums;
import com.mxpio.erp.common.technology.entity.Item;
import com.mxpio.erp.common.technology.service.ItemService;
import com.mxpioframework.common.util.SpringUtil;
import com.mxpioframework.common.vo.Result;
import com.mxpioframework.jpa.policy.CrudContext;
import com.mxpioframework.jpa.policy.impl.SmartCrudPolicyAdapter;
import com.mxpioframework.jpa.query.Criteria;
import com.mxpioframework.jpa.query.Operator;
import com.mxpioframework.system.service.SnRuleService;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
/**
 * @Author : 吴盼盼
 * @Datetime : 2022/9/15 10:16
 * @Desc :
 * @Modor :  Modifytime:
 * @modDesc :
 */
@Tag(name = "AssetBorrowApplyController", description = "资产借用归还接口")
@RestController
@RequestMapping("/erp/asset/borrowapply/")
public class AssetBorrowApplyController {
	@Autowired
	private BorrowApplyService borrowApplyService;
	@Autowired
	private BorrowApplyLineService borrowApplyLineService;
	@Autowired
	private BorrowOutMaterialService borrowOutMaterialService;
	@Autowired
	private BorrowOutMaterialFlowService borrowOutMaterialFlowService;
    @Autowired
    private ItemService itemService;
	
	@GetMapping("list")
    @Operation(summary = "借用申请列表", description = "获取借用申请列表（无分页）", method = "GET")
    public Result<List<BorrowApply>> list(@Parameter(name="查询参数")  Criteria criteria) throws UnsupportedEncodingException {
        List<BorrowApply> applyList = borrowApplyService.list(BorrowApply.class, criteria);
        return Result.OK(applyList);
    }
	
    @GetMapping("page")
    @Operation(summary = "借用申请列表", description = "获取借用申请列表（分页）", method = "GET")
    public Result<Page<BorrowApply>> page(@Parameter(name="查询参数")Criteria criteria, @Parameter(name="每页条数")Integer pageSize, @Parameter(name="页号")Integer pageNo) throws UnsupportedEncodingException {
        Pageable page = PageRequest.of(pageNo-1, pageSize);
        Page<BorrowApply> warehouseOrders = borrowApplyService.listPage(BorrowApply.class, page, criteria);
        return Result.OK(warehouseOrders);
    }

    @GetMapping("list/{bizNo}")
    @Operation(summary = "根据bizNo获取申请单", description = "根据bizNo获取申请单", method = "GET")
    public Result<BorrowApply> getById(@Parameter(name="业务单号") @PathVariable(name = "bizNo", required = true) String bizNo) {
    	BorrowApply borrowApply = borrowApplyService.getById(BorrowApply.class, bizNo);
        return Result.OK(borrowApply);
    }
    
    @RequestMapping("save")
    @Operation(summary = "保存申请单", description = "保存申请单")
    public Result<BorrowApply> save(@RequestBody BorrowApply warehouseOrder) {
    	if(StringUtils.isBlank(warehouseOrder.getBizNo())) {
    		SnRuleService snRuleService = SpringUtil.getBean(SnRuleService.class);
    		String expression = "BW";
    		String yearmonth = DateUtils.formatDate(new Date(), "yyyyMM");
			String bizNo = (String) snRuleService.execute(expression+yearmonth+"####", null);
			warehouseOrder.setBizNo(bizNo);//
            /*if (StringUtils.equals("1",warehouseOrder.getApplyType())){
                warehouseOrder.setBpmnStatus(OrderStatusEnums.BpmnStatus.AUDITED.getStatusCode());//如果是归还单，则保存时默认状态为已审核
            }*/
    	}
    	borrowApplyService.save(warehouseOrder,new SmartCrudPolicyAdapter(){
        	@Override
        	public boolean beforeInsert(CrudContext context) {
        		Object o = context.getEntity();
        		if(o instanceof BorrowApplyLine){
                    BorrowApply borrowApply = context.getParent();
                    ((BorrowApplyLine) o).setBizNo(borrowApply.getBizNo());
        		}
        		return true;
        	}
        });
        return Result.OK(warehouseOrder);
    }
    
    @DeleteMapping("remove/{bizNos}")
    @Operation(summary = "根据bizNos删除申请单", description = "删除申请单", method = "DELETE")
    @Transactional(readOnly = false)
    public Result<BorrowApply> remove(@Parameter(name="申请单号，多个单号用英文逗号分隔") @PathVariable(name = "bizNos", required = true) String bizNos) {
        String[] bizNo = bizNos.split(",");
        for(String key : bizNo){
        	Criteria c = Criteria.create().addCriterion("bizNo", Operator.EQ, key);
        	borrowApplyLineService.removeBatch(BorrowApplyLine.class, c);
        	borrowApplyService.delete(BorrowApply.class, key);
        }
        return Result.OK();
    }
    
	@PutMapping("open/{bizNo}")
    @Operation(summary = "打开申请单", description = "打开申请单", method = "PUT")
    public Result<BorrowApply> open(@Parameter(name="业务单号") @PathVariable(name = "bizNo", required = true) String bizNo) {
    	return borrowApplyService.updateCloseStatus(bizNo, OrderStatusEnums.CloseStatus.OPEN);
    }

    @PutMapping("close/{bizNo}")
    @Operation(summary = "关闭申请单", description = "关闭申请单", method = "PUT")
    public Result<BorrowApply> close(@Parameter(name="业务单号") @PathVariable(name = "bizNo", required = true) String bizNo) {
    	return borrowApplyService.updateCloseStatus(bizNo, OrderStatusEnums.CloseStatus.CLOSED);
    }
    
    @PutMapping("submit/{bizNo}")
    @Operation(summary = "提交申请单", description = "提交申请单", method = "PUT")
    public Result<BorrowApply> submit(@Parameter(name="业务单号") @PathVariable(name = "bizNo", required = true) String bizNo) {
    	return borrowApplyService.updateBpmnStatus(bizNo, OrderStatusEnums.BpmnStatus.AUDITING);
    }
    
    @PutMapping("audit/{bizNo}")
    @Operation(summary = "审核申请单", description = "审核申请单", method = "PUT")
    public Result<BorrowApply> audit(@Parameter(name="业务单号") @PathVariable(name = "bizNo", required = true) String bizNo) {
    	return borrowApplyService.updateBpmnStatus(bizNo, OrderStatusEnums.BpmnStatus.AUDITED);
    }
    
    @PutMapping("abandon/{bizNo}")
    @Operation(summary = "弃审申请单", description = "弃审申请单", method = "PUT")
    public Result<BorrowApply> abandon(@Parameter(name="业务单号") @PathVariable(name = "bizNo", required = true) String bizNo) {
    	return borrowApplyService.updateBpmnStatus(bizNo, OrderStatusEnums.BpmnStatus.CREATE);
    }

    @RequestMapping("excute/{bizNo}/{applyType}")
    @Operation(summary = "执行申请单", description = "执行申请单")
    public Result<BorrowApply> excute(@PathVariable(name = "bizNo", required = true) String bizNo,@PathVariable(name = "applyType", required = true) String applyType,
                @RequestBody OrderExcuteVo orderExcuteVo) {
        Result<BorrowApply> result = null;
        try {
            result = borrowApplyService.execute(bizNo,applyType,orderExcuteVo);
        } catch (MBootException e) {
            return Result.error(e.getMessage());
        }
        return result;
    }

    @GetMapping("borrowOutMaterialPage")
    @Operation(summary = "获取已借出物资列表", description = "获取已借出物资列表（分页）", method = "GET")
    public Result<Page<BorrowOutMaterial>> borrowOutMaterialPage(@Parameter(name="查询参数")Criteria criteria, @Parameter(name="每页条数")Integer pageSize, @Parameter(name="页号")Integer pageNo) throws UnsupportedEncodingException {
        Pageable page = PageRequest.of(pageNo-1, pageSize);
        criteria.addCriterion("quantity",Operator.GT, BigDecimal.ZERO);//增加固定过滤条件
        Page<BorrowOutMaterial> warehouseOrders = borrowOutMaterialService.listPage(BorrowOutMaterial.class, page, criteria);
        List<BorrowOutMaterial> content = warehouseOrders.getContent();
        Map<String,Item> itemMap = new HashMap<>();
        for (BorrowOutMaterial borrowOutMaterial:content){//关联item冗余展示字段信息
            Item item = null;
            if (itemMap.containsKey(borrowOutMaterial.getItemCode())){
                item = itemMap.get(borrowOutMaterial.getItemCode());
            }else{
                item = itemService.getById(Item.class,borrowOutMaterial.getItemCode());
                itemMap.put(borrowOutMaterial.getItemCode(),item);
            }
            borrowOutMaterial.setItemName(item.getItemName());
            borrowOutMaterial.setItemSpec(item.getItemSpec());
            borrowOutMaterial.setUnitCode(item.getUnitCode());
        }
        return Result.OK(warehouseOrders);
    }

}
